package com.yx.serial;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.LongDef;
import androidx.appcompat.app.AppCompatActivity;

import com.yx.MainActivity2;
import com.yx.serialport.SerialPort;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import android.widget.ArrayAdapter;
import android.widget.RadioGroup;
import android.widget.Spinner;

public class MainActivity extends AppCompatActivity {

    private Spinner spinnerPorts, spinnerBaudrate, spinnerDatabits, spinnerStopbits, spinnerParity;
    private RadioGroup rgSendFormat;
    private EditText etSend;
    private TextView tvReceived;
    private Button btnOpen, btnSend, btnClear,btnOpen1,btnOpen2,btnOpen3,sendtest,getTem,sendtest2;

    private SerialPort serialPort;
    private InputStream inputStream;
    private OutputStream outputStream;
    private boolean isOpen = false;
    private boolean isOpen1 = false;
    private boolean isOpen2 = false;
    private boolean isOpen3 = false;
    private ReadThread readThread;

    // 可用的串口设备列表（根据实际情况修改）
    private final String[] portDevices = {
            "/dev/ttyS4",
            "/dev/ttyS1",
            "/dev/ttyS2",
            "/dev/ttyS3",
            "/dev/ttyUSB0",
            "/dev/ttyUSB1"
    };
ScrollView scrollView;
    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case 0: // 更新接收数据
                    String data = (String) msg.obj;
                    tvReceived.append(data);

                    scrollView.post(() -> scrollView.fullScroll(View.FOCUS_DOWN));
                    break;
                case 1: // 显示错误信息
                    Toast.makeText(MainActivity.this, (String) msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case 2: // 更新串口状态
                    boolean opened = (boolean) msg.obj;
                    isOpen = opened;
                    btnOpen.setText(opened ? "关闭串口" : "打开串口");
                    break;
            }
            return false;
        }
    });
    private List<String> availablePorts = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        scrollView=findViewById(R.id.scrollView);
        initViews();
        loadSerialPorts();
        initSpinners();
        setListeners();
    }
    private void loadSerialPorts() {
        // 获取所有可能的串口设备
        List<String> allPorts = SerialPort.getPossibleSerialPorts();

        // 获取有权限的串口设备
        availablePorts = SerialPort.getAvailableSerialPorts();

        // 如果没有有权限的设备，尝试获取权限
        if (availablePorts.isEmpty() && !allPorts.isEmpty()) {
            for (String port : allPorts) {
                Log.d(TAG, "loadSerialPorts: "+port);
                if (SerialPort.acquireSerialPortPermission(port)) {
                    availablePorts.add(port);
                }
            }
        }

        // 如果还是没有可用设备，显示所有可能的设备（用户可以选择后尝试获取权限）
        if (availablePorts.isEmpty()) {
            availablePorts = allPorts;
        }
        availablePorts.add("/dev/ttyS1");
        Log.d(TAG, "可用串口设备: " + availablePorts);
    }
    private void initViews() {
        spinnerPorts = findViewById(R.id.spinner_ports);
        spinnerBaudrate = findViewById(R.id.spinner_baudrate);
        spinnerDatabits = findViewById(R.id.spinner_databits);
        spinnerStopbits = findViewById(R.id.spinner_stopbits);
        spinnerParity = findViewById(R.id.spinner_parity);
        rgSendFormat = findViewById(R.id.rg_send_format);
        etSend = findViewById(R.id.et_send);
        tvReceived = findViewById(R.id.tv_received);
        btnOpen = findViewById(R.id.btn_open);
        btnOpen1 = findViewById(R.id.btn_open1);
        btnOpen2 = findViewById(R.id.btn_open2);
        btnOpen3 = findViewById(R.id.btn_open3);
        btnSend = findViewById(R.id.btn_send);
        btnClear = findViewById(R.id.btn_clear);
        sendtest = findViewById(R.id.sendtest);
        sendtest2 = findViewById(R.id.sendtest2);
        getTem = findViewById(R.id.getTem1);
    }

    private void initSpinners() {
        // 初始化串口设备下拉框
        ArrayAdapter<String> portAdapter = new ArrayAdapter<>(this,
                android.R.layout.simple_spinner_item, availablePorts);
        portAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerPorts.setAdapter(portAdapter);
        // 如果有可用设备，默认选择第一个
        if (!availablePorts.isEmpty()) {
            spinnerPorts.setSelection(0);
        } else {
            Toast.makeText(this, "未检测到可用串口设备", Toast.LENGTH_LONG).show();
        }
        // 初始化波特率下拉框
        int[] baudrates = SerialPort.getSupportedBaudrates();
        String[] baudrateStrs = new String[baudrates.length];
        for (int i = 0; i < baudrates.length; i++) {
            baudrateStrs[i] = String.valueOf(baudrates[i]);
        }
        ArrayAdapter<String> baudrateAdapter = new ArrayAdapter<>(this,
                android.R.layout.simple_spinner_item, baudrateStrs);
        baudrateAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerBaudrate.setAdapter(baudrateAdapter);
        // 默认选择9600
        for (int i = 0; i < baudrates.length; i++) {
            if (baudrates[i] == 9600) {
                spinnerBaudrate.setSelection(i);
                break;
            }
        }

        // 初始化数据位下拉框
        int[] databits = SerialPort.getSupportedDataBits();
        String[] databitStrs = new String[databits.length];
        for (int i = 0; i < databits.length; i++) {
            databitStrs[i] = String.valueOf(databits[i]);
        }
        ArrayAdapter<String> databitAdapter = new ArrayAdapter<>(this,
                android.R.layout.simple_spinner_item, databitStrs);
        databitAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerDatabits.setAdapter(databitAdapter);
        // 默认选择8
        spinnerDatabits.setSelection(3);

        // 初始化停止位下拉框
        int[] stopbits = SerialPort.getSupportedStopBits();
        String[] stopbitStrs = new String[stopbits.length];
        for (int i = 0; i < stopbits.length; i++) {
            stopbitStrs[i] = String.valueOf(stopbits[i]);
        }
        ArrayAdapter<String> stopbitAdapter = new ArrayAdapter<>(this,
                android.R.layout.simple_spinner_item, stopbitStrs);
        stopbitAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerStopbits.setAdapter(stopbitAdapter);
        // 默认选择1
        spinnerStopbits.setSelection(0);

        // 初始化校验位下拉框
        int[] parityValues = SerialPort.getSupportedParity();
        String[] parityStrs = new String[parityValues.length];
        for (int i = 0; i < parityValues.length; i++) {
            parityStrs[i] = SerialPort.getParityName(parityValues[i]);
        }
        ArrayAdapter<String> parityAdapter = new ArrayAdapter<>(this,
                android.R.layout.simple_spinner_item, parityStrs);
        parityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerParity.setAdapter(parityAdapter);
        // 默认选择无校验
        spinnerParity.setSelection(0);
    }
boolean istest;
    private void setListeners() {
        btnOpen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isOpen) {
                    closeSerialPort();
                } else {
                    openSerialPort(false,"",1,1,1,1);
                }
            }
        });
        btnOpen1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isOpen) {
                    istest=false;
                    closeSerialPort();
                } else {
                    openSerialPort(true,"/dev/ttyS0",1200,8,1,2);
                }
            }
        });
        btnOpen2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isOpen) {
                    istest=false;
                    closeSerialPort();
                } else {
                    openSerialPort(true,"/dev/ttyS3",9600,8,1,0);
                }
            }
        });
        getTem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               startActivity(new Intent(MainActivity.this, MainActivity2.class));
            }
        });
        btnOpen3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isOpen) {
                    istest=false  ;
                    closeSerialPort();
                } else {
                    openSerialPort(true,"/dev/ttyS2",115200,8,1,0);
                }
            }
        });
        sendtest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                istest=true;
                sendData(true,"68aaaaaaaaaaaa681300DF16");
            }
        });
        sendtest2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                istest=true;
                sendData(true,"e90002000cf7e6");
            }
        });

        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                istest=false;
                sendData(false,"");
            }
        });

        btnClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tvReceived.setText("");
            }
        });
    }
    // 在打开串口前检查权限
    private boolean checkSerialPortPermission(File device) {
        try {
            // 尝试获取 root 权限
            Process su = Runtime.getRuntime().exec("su");
            String cmd = "chmod 666 " + device.getAbsolutePath() + "\n" + "exit\n";
            su.getOutputStream().write(cmd.getBytes());
            su.waitFor();

            return device.canRead() && device.canWrite();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    private void openSerialPort(boolean istest,String port1,int bbaudrate1,int databits1,int stopbits1,int parity1) {
        String port;
        int baudrate;
        int databits;
        int stopbits;
        int parity;
        try {
            if (istest){
                port=port1;
                baudrate=bbaudrate1;
                databits=databits1;
                stopbits=stopbits1;
                parity= parity1;
            }else{
                // 获取选择的参数
                port = (String) spinnerPorts.getSelectedItem();
                baudrate = Integer.parseInt((String) spinnerBaudrate.getSelectedItem());
                databits = Integer.parseInt((String) spinnerDatabits.getSelectedItem());
                stopbits = Integer.parseInt((String) spinnerStopbits.getSelectedItem());
                parity = spinnerParity.getSelectedItemPosition(); // 0:无, 1:奇, 2:偶
            }

//            Log.d(TAG, "openSerialPort: "+checkSerialPortPermission(new File(port)));
            // 打开串口
            Log.d(TAG, "openSerialPort: "+port+" "+baudrate+" "+databits+" "+stopbits+" "+parity);
            serialPort = new SerialPort(new File(port), baudrate, databits, stopbits, parity, 0);
            inputStream = serialPort.getInputStream();
            outputStream = serialPort.getOutputStream();

            // 启动读取线程
            readThread = new ReadThread();
            readThread.start();

            // 更新状态
            handler.sendMessage(handler.obtainMessage(2, true));
            Toast.makeText(this, "串口打开成功", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
            handler.sendMessage(handler.obtainMessage(1, "串口打开失败: " + e.getMessage()));
        }
    }

    private void closeSerialPort() {
        try {
            if (readThread != null) {
                readThread.interrupt();
                readThread = null;
            }

            if (serialPort != null) {
                serialPort.close1();
                serialPort = null;
            }
            inputStream = null;
            outputStream = null;
            // 更新状态
            handler.sendMessage(handler.obtainMessage(2, false));
            Toast.makeText(this, "串口已关闭", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendData(boolean istest,String data1) {
        if (!isOpen || outputStream == null) {
            Toast.makeText(this, "请先打开串口", Toast.LENGTH_SHORT).show();
            return;
        }
        String data = null;
        int selectedId;
        if (istest){
            data = data1.toString();

        }else{
            data = etSend.getText().toString();
        }

        Log.d(TAG, "sendData: "+data);
        if (data.isEmpty()) {
            Toast.makeText(this, "请输入要发送的数据", Toast.LENGTH_SHORT).show();
            return;
        }

        try {
            if (istest){

                selectedId=R.id.rb_hex;

            }else {
                selectedId = rgSendFormat.getCheckedRadioButtonId();
            }

            byte[] sendData;

            if (selectedId == R.id.rb_string) {
                // 字符串格式
                sendData = data.getBytes();
                Log.d(TAG, "sendData1: ");
            } else {
                // 16进制格式
                sendData = hexStringToByteArray(data.replace(" ", ""));
                Log.d(TAG, "sendData2: ");
            }

            outputStream.write(sendData);
            outputStream.flush();

            // 显示发送的数据
            String sendText = "发送: " + data + "\n";
            handler.sendMessage(handler.obtainMessage(0, sendText));

//            etSend.setText("");
        } catch (Exception e) {
            e.printStackTrace();
            handler.sendMessage(handler.obtainMessage(1, "发送失败: " + e.getMessage()));
        }
    }

    // 16进制字符串转字节数组
    // 16进制字符串转字节数组
    private byte[] hexStringToByteArray(String s) {
        // 移除所有空格
        s = s.replace(" ", "");

        // 检查字符串长度是否为奇数
        if (s.length() % 2 != 0) {
            // 如果是奇数，在前面补0
            s = "0" + s;
            // 或者可以选择抛出异常或提示用户
            // throw new IllegalArgumentException("16进制字符串长度必须为偶数");
        }

        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            // 确保不会越界
            if (i + 1 < len) {
                data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                        + Character.digit(s.charAt(i+1), 16));
            }
        }
        return data;
    }

    // 字节数组转16进制字符串
    private String byteArrayToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString();
    }
String TAG="MainActivity";
    // 读取串口数据的线程
    // 修改读取线程，添加更多日志和错误处理
    // 修改读取线程，添加更多日志和错误处理
    private class ReadThread extends Thread {
        @Override
        public void run() {
            super.run();
            byte[] buffer = new byte[1024];
            int size;

            while (!isInterrupted()) {
                try {
                    if (inputStream == null) {
                        Log.e(TAG, "输入流为空");
//                        break;
                    }

                    // 检查是否有数据可读

                        size = inputStream.read(buffer);
                    Log.d(TAG, "run111: "+inputStream.available());
                        if (size > 0) {
                            // 获取当前选择的接收格式
                            int selectedId;
                            if (istest){
                                selectedId=R.id.rb_hex;
                            }else{
                                selectedId = rgSendFormat.getCheckedRadioButtonId();
                            }

                            String data;
                            Log.d(TAG, "run: "+size);
                            if (selectedId == R.id.rb_string) {
                                // 字符串格式
                                data = new String(buffer, 0, size);
                            } else {
                                // 16进制格式
                                data = byteArrayToHexString(buffer, size);
                            }

                            String receivedText = "接收: " + data + "\n";
                            Log.d(TAG, "接收到数据: " + data);
                            handler.sendMessage(handler.obtainMessage(0, receivedText));
                        }

                } catch (IOException e) {
                    Log.e(TAG, "读取数据失败: " + e.getMessage());
                    handler.sendMessage(handler.obtainMessage(1, "读取数据失败: " + e.getMessage()));
//                    break;
                }
            }
            Log.d(TAG, "读取线程结束");
        }
    }

    // 改进的字节数组转16进制字符串方法


    // 改进的字节数组转16进制字符串方法
    private String byteArrayToHexString(byte[] bytes, int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(String.format("%02X ", bytes[i]));
        }
        return sb.toString().trim();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        closeSerialPort();
    }
}